#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# Filename: performance_info.py
# Author: ChenChangSong
# Date: 2025-08-24

"""
功能描述: 获取填写绩效的信息
"""
import sys
import time
from pathlib import Path
import pandas as pd
sys.path.append(str(Path(__file__).resolve().parent.parent.parent))

from comm.common_code import *
from comm.common_code import get_excel_data, logger, log_to_ui_info, log_to_ui_error
from tapd_capture_api.requirements.get_common__info import req_common_get_info
from tapd_capture_api.requirements.req_test_case import req_test_case_info
from tapd_capture_api.requirements.req_bugs_list import req_test_bug_info

from tapd_capture_api.requirements.published_requirements import req_get_published_requirements

def get_performance_info(name_value,time_value):
    """获取填写绩效的信息"""
    rules_info = """
    规则：
        1.  已发布需求按"需求实际发版时间"统计：
            需求等级、测试用例总数、冒烟用例数

        2.bug
            内部bug：缺陷根源为"内部模板"，
            线上bug: 缺陷根源为"线上模板"
            有效：非 同意拒绝|已拒绝（不予受理）|已确认未复现|拒绝(内部bug)|拒绝（线上：重复/非问题）
            逃逸率 = 线上有效bug/(内部有效bug+线上有效bug)*100%
    """
    performance_info = f'{rules_info}\n\n查询测试人员:{name_value},查询时间段：{time_value}(可查询任意人员、任意时间区间):\n\n'

    req_priority_dit = {} # 存需求等级
    total_case = 0  # 用例总数
    m_y_case_num = 0 # 冒烟用例数
    req_info = {} # 需求信息
 

    # 1、获取已上线的需求ID,获取需求等级、用例总数、冒烟用例数
    id_dict = req_get_published_requirements(name_value,time_value)
    if id_dict:
        logger.info(f"获取到{len(id_dict)}个已发布需求ID")
        # 1.1、获取需求等级
        for key, value in id_dict.items():
            logger.info(f"已发布需求ID：{key}")
            priority = req_common_get_info(req_id=key)
            
            # 1.2、用例总数、冒烟用例数
            case_num_s,m_y_case_num_s = req_test_case_info(req_id=key)
            total_case += case_num_s
            m_y_case_num += m_y_case_num_s
    
            #  bug总数，有效线上bug，无效线上bug，有效内部bug，无效内部bug
            total_bug, effective_online_bug_num, invalid_online_bug_num,effective_test_bug_num,invalid_test_bug_num = req_test_bug_info(req_id=key)
            
            # 存储所有信息，确保优先级信息不会被覆盖
            req_info[key] = {
                "priority": priority,
                "test_case_total_count": case_num_s,
                "smoke_case_count": m_y_case_num_s,
                "total_bug": total_bug,
                "effective_online_bug_num": effective_online_bug_num,
                "invalid_online_bug_num": invalid_online_bug_num,
                "effective_test_bug_num": effective_test_bug_num,
                "invalid_test_bug_num": invalid_test_bug_num
            }
    else:
        logger.warning("未获取到任何已发布需求ID")
        log_to_ui_error("未获取到任何已发布需求ID")

    # 统计不同等级需求的数量、bug数量和用例数
    priority_count = {'S': 0, 'A': 0, 'B': 0, 'C': 0, 'X': 0}
    priority_test_bugs = {'S': 0, 'A': 0, 'B': 0, 'C': 0, 'X': 0}  # 有效内部Bug数量
    priority_online_bugs = {'S': 0, 'A': 0, 'B': 0, 'C': 0, 'X': 0}  # 有效线上Bug数量
    priority_test_cases = {'S': 0, 'A': 0, 'B': 0, 'C': 0, 'X': 0}  # 用例数量
    valid_priorities = {'S', 'A', 'B', 'C'}
    
    # 汇总bug信息
    total_bug_sum = 0       # 总bug数
    effective_bug_sum = 0
    invalid_bug_sum = 0
    total_effective_online_bug = 0
    total_effective_test_bug = 0
    
    # 遍历所有需求信息进行统计
    for req_id, info in req_info.items():
        # 统计需求等级
        if 'priority' in info:
            priority = info['priority']
            if priority in valid_priorities:
                priority_count[priority] += 1
                # 按等级统计有效内部Bug数量
                priority_test_bugs[priority] += info.get('effective_test_bug_num', 0)
                # 按等级统计有效线上Bug数量
                priority_online_bugs[priority] += info.get('effective_online_bug_num', 0)
                # 按等级统计用例数
                priority_test_cases[priority] += info.get('test_case_total_count', 0)
            else:
                priority_count['X'] += 1
                # 按等级统计有效内部Bug数量
                priority_test_bugs['X'] += info.get('effective_test_bug_num', 0)
                # 按等级统计有效线上Bug数量
                priority_online_bugs['X'] += info.get('effective_online_bug_num', 0)
                # 按等级统计用例数
                priority_test_cases['X'] += info.get('test_case_total_count', 0)
        
        # 汇总bug信息
        total_bug_sum += info.get('total_bug', 0)
        effective_online_bug = info.get('effective_online_bug_num', 0)
        effective_test_bug = info.get('effective_test_bug_num', 0)
        invalid_online_bug = info.get('invalid_online_bug_num', 0)
        invalid_test_bug = info.get('invalid_test_bug_num', 0)
        
        effective_bug_sum += effective_online_bug + effective_test_bug
        invalid_bug_sum += invalid_online_bug + invalid_test_bug
        total_effective_online_bug += effective_online_bug
        total_effective_test_bug += effective_test_bug
    
    # 计算逃逸率
    escape_rate = 0
    if total_effective_online_bug + total_effective_test_bug != 0:
        escape_rate = (total_effective_online_bug / (total_effective_online_bug + total_effective_test_bug)) * 100
    
    # 组装最终输出信息
    performance_info += f"已上线需求总数：{len(id_dict)}个\n"
    performance_info += f"已上线需求等级统计：S级需求：{priority_count['S']}个，A级需求：{priority_count['A']}个，B级需求：{priority_count['B']}个，C级需求：{priority_count['C']}个，X级需求：{priority_count['X']}个\n\n"
    performance_info += f"提出有效内部Bug总数量：{total_effective_test_bug}个\n"
    performance_info += f"提出有效内部Bug数量：S级需求：{priority_test_bugs['S']}个，A级需求：{priority_test_bugs['A']}个，B级需求：{priority_test_bugs['B']}个，C级需求：{priority_test_bugs['C']}个，X级需求：{priority_test_bugs['X']}个\n\n"
    performance_info += f"处理有效线上Bug数量：S级需求：{priority_online_bugs['S']}个，A级需求：{priority_online_bugs['A']}个，B级需求：{priority_online_bugs['B']}个，C级需求：{priority_online_bugs['C']}个，X级需求：{priority_online_bugs['X']}个\n\n"
    performance_info += f"编写的用例总数：{total_case}条\n"
    performance_info += f"编写的用例数:S级需求：{priority_test_cases['S']}条，A级需求：{priority_test_cases['A']}条，B级需求：{priority_test_cases['B']}条，C级需求：{priority_test_cases['C']}条，X级需求：{priority_test_cases['X']}条\n\n"
    # 线上Bug数为所有需求等级的有效线上Bug数量相加之和
    performance_info += f"需求对应的线上Bug数:{total_effective_online_bug}个，事故数:手动填写，逃逸率:{escape_rate:.2f}%\n"
    
    # 输出日志信息
    log_to_ui_info("↑↑↑=================================================↑↑↑")
    logger.info(performance_info)
    log_to_ui_info(performance_info)
    log_to_ui_info("↑↑↑=================================================↑↑↑")
    
    # 导出Excel文件
    export_performance_to_excel(req_info, name_value, time_value)
    
    return performance_info


def export_performance_to_excel(req_info, name_value, time_value):
    """
    将需求绩效信息导出到Excel文件
    :param req_info: 需求信息字典
    :param name_value: 测试人员姓名
    :param time_value: 查询时间范围
    """
    excel_data = get_excel_data()

    try:
        # 创建数据列表
        data = []
        
        # 计算合计数据
        total_test_cases = 0
        total_smoke_cases = 0
        total_effective_test_bugs = 0
        total_invalid_test_bugs = 0
        total_effective_online_bugs = 0
        total_invalid_online_bugs = 0
        
        # 获取项目ID
        project_id = excel_data.get('项目ID', '')
        
        # 准备数据
        for req_id, info in req_info.items():
            # 累加合计数据
            total_test_cases += info.get('test_case_total_count', 0)
            total_smoke_cases += info.get('smoke_case_count', 0)
            total_effective_test_bugs += info.get('effective_test_bug_num', 0)
            total_invalid_test_bugs += info.get('invalid_test_bug_num', 0)
            total_effective_online_bugs += info.get('effective_online_bug_num', 0)
            total_invalid_online_bugs += info.get('invalid_online_bug_num', 0)
            
            # 计算非冒烟测试用例数和bug密度
            test_case_total = info.get('test_case_total_count', 0)  # 测试用例总数
            smoke_case_count = info.get('smoke_case_count', 0)  # 冒烟用例数
            test_case_count = test_case_total - smoke_case_count  # 测试用例数（非冒烟）
            effective_test_bug_num = info.get('effective_test_bug_num', 0)
            
            # 计算bug密度，如果非冒烟测试用例数为0则密度为0
            bug_density = round(effective_test_bug_num / test_case_count, 2) if test_case_count > 0 else 0
            
            # 添加每行数据
            data.append({
                '需求ID': req_id,
                '需求等级': info.get('priority', ''),
                '测试用例数': test_case_count,  # 非冒烟测试用例数
                '冒烟用例数': smoke_case_count,
                '测试用例总数': test_case_total,
                '有效内部bug数': effective_test_bug_num,
                '无效内部bug数': info.get('invalid_test_bug_num', 0),
                '有效线上bug数': info.get('effective_online_bug_num', 0),
                '无效线上bug数': info.get('invalid_online_bug_num', 0),
                'bug密度(0.15~0.18)': bug_density
            })
        
        # 计算合计行的测试用例数和bug密度
        total_test_case_total_count = total_test_cases - total_smoke_cases  # 合计非冒烟测试用例数
        total_bug_density = round(total_effective_test_bugs / total_test_case_total_count, 2) if total_test_case_total_count > 0 else 0
        
        # 插入合计行作为第一行
        data.insert(0, {
            '需求ID': '合计',
            '需求等级': '',
            '测试用例数': total_test_case_total_count,
            '冒烟用例数': total_smoke_cases,
            '测试用例总数': total_test_cases,
            '有效内部bug数': total_effective_test_bugs,
            '无效内部bug数': total_invalid_test_bugs,
            '有效线上bug数': total_effective_online_bugs,
            '无效线上bug数': total_invalid_online_bugs,
            'bug密度(0.15~0.18)': total_bug_density
        })
        
        # 创建DataFrame
        df = pd.DataFrame(data)
        
        # 生成文件名：使用time_value参数，将时间范围转换为适合文件名的格式
        # 移除时间字符串中的空格和冒号，替换逗号为下划线
        safe_time_value = time_value.replace(' ', '').replace(':', '').replace(',', '_')
        filename = f"绩效_{safe_time_value}.xlsx"
        
        # 确保目录存在 - 使用app_dir构建路径
        output_dir = app_dir / 'files' / '导出(可删除子文件)'
        output_dir.mkdir(parents=True, exist_ok=True)
        
        # 保存Excel文件并设置列宽和超链接
        excel_path = output_dir / filename
        with pd.ExcelWriter(excel_path, engine='xlsxwriter') as writer:
            df.to_excel(writer, index=False, sheet_name='绩效信息')
            
            # 获取worksheet对象
            worksheet = writer.sheets['绩效信息']
            
            # 设置所有列的宽度为20
            for col_idx, col in enumerate(df.columns):
                worksheet.set_column(col_idx, col_idx, 20)
            
            # 为需求ID添加超链接（跳过合计行）
            for row_idx in range(1, len(df)):  # 从第2行开始（索引1），第1行是合计
                req_id = df.iloc[row_idx]['需求ID']
                if project_id:
                    req_url = f"https://www.tapd.cn/tapd_fe/{project_id}/story/detail/{req_id}"
                    # 设置超链接格式
                    worksheet.write_url(row_idx + 1, 0, req_url, string=str(req_id))
                else:
                    # 如果没有项目ID，只写入需求ID
                    worksheet.write(row_idx + 1, 0, req_id)
        
        logger.info(f"超详细绩效信息已成功导出到: {excel_path}\n请到该路径下查看！")
        log_to_ui_info(f"超详细绩效信息已成功导出到: {excel_path}\n请到该路径下查看！")

        
    except Exception as e:
        logger.error(f"导出Excel文件失败: {str(e)}")
        log_to_ui_error(f"导出Excel文件失败: {str(e)}")


if __name__ == '__main__':
    # get_performance_info(name_value='陈昌松',time_value='2025-09-09 00:00,2025-09-30 23:59')
    get_performance_info(name_value='李玉娇',time_value='2025-11-03 00:00,2025-11-09 23:59')